package com.example.sonone.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import com.example.sonone.pojo.SkcRelLabelEntity;
import com.example.sonone.pojo.SkcRelLabelEntityExample;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

/**
*SkcRelLabelMapper
* @author Shein Generator
* @since 2022/07/01
*/
@Repository
public interface SkcRelLabelMapper {
    /**
    * countByExample
    * @param example example
    * @return long long
    */
    long countByExample(SkcRelLabelEntityExample example);

    /**
    * deleteByExample
    * @param example example
    * @return int int
    */
    int deleteByExample(SkcRelLabelEntityExample example);

    /**
    * deleteByPrimaryKey
    * @param id id
    * @return int int
    */
    int deleteByPrimaryKey(Long id);

    /**
    * insert
    * @param record record
    * @return int int
    */
    int insert(SkcRelLabelEntity record);

    /**
    * insertSelective
    * @param record record
    * @return int int
    */
    int insertSelective(SkcRelLabelEntity record);

    /**
    * selectByExample
    * @param example example
    * @return List<SkcRelLabelEntity> List<SkcRelLabelEntity>
    */
    List<SkcRelLabelEntity> selectByExample(SkcRelLabelEntityExample example);

    /**
    * selectByPrimaryKey
    * @param id id
    * @return SkcRelLabelEntity SkcRelLabelEntity
    */
    SkcRelLabelEntity selectByPrimaryKey(Long id);

    /**
    * updateByExampleSelective
    * @param record record
    * @param example example
    * @return int int
    */
    int updateByExampleSelective(@Param("record") SkcRelLabelEntity record, @Param("example") SkcRelLabelEntityExample example);

    /**
    * updateByExample
    * @param record record
    * @param example example
    * @return int int
    */
    int updateByExample(@Param("record") SkcRelLabelEntity record, @Param("example") SkcRelLabelEntityExample example);

    /**
    * updateByPrimaryKeySelective
    * @param record record
    * @return int int
    */
    int updateByPrimaryKeySelective(SkcRelLabelEntity record);

    /**
    * updateByPrimaryKey
    * @param record record
    * @return int int
    */
    int updateByPrimaryKey(SkcRelLabelEntity record);

    /**
    * batchInsertSelective
    * @param recordList recordList
    * @param selective selective
    * @return int int
    */
    int batchInsertSelective(@Param("recordList") List<SkcRelLabelEntity> recordList, @Param("selective") SkcRelLabelEntity selective);

    /**
    * batchUpdate
    * @param recordList recordList
    * @return int int
    */
    int batchUpdate(@Param("recordList") List<SkcRelLabelEntity> recordList);

    /**
    * foreachUpdate
    * @param recordList recordList
    * @return int int
    */
    int foreachUpdate(@Param("recordList") List<SkcRelLabelEntity> recordList);

    /**
    * batchDelete
    * @param ids ids
    * @return int int
    */
    int batchDelete(@Param("ids") Long[] ids);

    /**
    * selectiveByExample
    * @param example example
    * @param selective selective
    * @return List<SkcRelLabelEntity> List<SkcRelLabelEntity>
    */
    List<SkcRelLabelEntity> selectiveByExample(@Param("example") SkcRelLabelEntityExample example, @Param("selective") SkcRelLabelEntity selective);

    /**
    * selectiveByPrimaryKey
    * @param id id
    * @param selective selective
    * @return SkcRelLabelEntity SkcRelLabelEntity
    */
    SkcRelLabelEntity selectiveByPrimaryKey(@Param("id") Long id, @Param("selective") SkcRelLabelEntity selective);

    /**
    * selectToList
    * @param valueFun valueFun
    * @param selectiveConsumer selectiveConsumer
    * @param exampleSupplier exampleSupplier
    * @param criteriaConsumer criteriaConsumer
    * @return List<V> List<V>
    */
    default <V> List<V> selectToList(Function<SkcRelLabelEntity, V> valueFun, Consumer<SkcRelLabelEntity.SkcRelLabelEntityBuilder> selectiveConsumer, Supplier<SkcRelLabelEntityExample> exampleSupplier, Consumer<SkcRelLabelEntityExample.Criteria> criteriaConsumer) {
        SkcRelLabelEntity.SkcRelLabelEntityBuilder builder = SkcRelLabelEntity.builder();
        selectiveConsumer.accept(builder);
        SkcRelLabelEntityExample example = exampleSupplier.get();
        criteriaConsumer.accept(example.createCriteria());
        return selectiveByExample(example, builder.build()).stream().map(valueFun).collect(Collectors.toList());
    }

    /**
    * selectToMap
    * @param keyFun keyFun
    * @param valueFun valueFun
    * @param selectiveConsumer selectiveConsumer
    * @param exampleSupplier exampleSupplier
    * @param criteriaConsumer criteriaConsumer
    * @return Map<K, V> Map<K, V>
    */
    default <K, V> Map<K, V> selectToMap(Function<SkcRelLabelEntity, K> keyFun, Function<SkcRelLabelEntity, V> valueFun, Consumer<SkcRelLabelEntity.SkcRelLabelEntityBuilder> selectiveConsumer, Supplier<SkcRelLabelEntityExample> exampleSupplier, Consumer<SkcRelLabelEntityExample.Criteria> criteriaConsumer) {
        SkcRelLabelEntity.SkcRelLabelEntityBuilder builder = SkcRelLabelEntity.builder();
        selectiveConsumer.accept(builder);
        SkcRelLabelEntityExample example = exampleSupplier.get();
        criteriaConsumer.accept(example.createCriteria());
        return selectiveByExample(example, builder.build()).stream().collect(Collectors.toMap(keyFun, valueFun, (v1, v2) -> v1));
    }

    /**
    * selectiveDb
    * @param valueFun valueFun
    * @param selectiveCon selectiveCon
    * @param conditionCon conditionCon
    * @return List<V> List<V>
    */
    default <V> List<V> selectiveDb(Function<SkcRelLabelEntity, V> valueFun,
                                    Consumer<SkcRelLabelEntity> selectiveCon, Consumer<SkcRelLabelEntityExample> conditionCon) {
        SkcRelLabelEntity selective = new SkcRelLabelEntity();
        SkcRelLabelEntityExample example = new SkcRelLabelEntityExample();
        selectiveCon.accept(selective);
        if (conditionCon != null) {
            conditionCon.accept(example);
        }
        return selectiveByExample(example,selective).stream()
        .map(valueFun)
        .collect(Collectors.toList());
    }

    /**
    * mapDb
    * @param keyFun keyFun
    * @param valueFun valueFun
    * @param selectiveCon selectiveCon
    * @param conditionCon conditionCon
    * @return Map<K, V> Map<K, V>
    */
    default <K, V> Map<K, V> mapDb(Function<SkcRelLabelEntity, K> keyFun, Function<SkcRelLabelEntity, V> valueFun, Consumer<SkcRelLabelEntity> selectiveCon, Consumer<SkcRelLabelEntityExample> conditionCon) {
        SkcRelLabelEntity selective = new SkcRelLabelEntity();
        SkcRelLabelEntityExample example = new SkcRelLabelEntityExample();
        selectiveCon.accept(selective);
        if (conditionCon != null) {
            conditionCon.accept(example);
        }
        return selectiveByExample(example,selective).stream()
        .collect(HashMap::new, (m,v)->m.put(keyFun.apply(v), valueFun.apply(v)), HashMap::putAll);
    }

    /**
    * loopDo
    * @param batchSize batchSize
    * @param selectiveCon selectiveCon
    * @param conditionCon conditionCon
    * @param batchConsumer batchConsumer
    * @return void void
    */
    default void loopDo(Integer batchSize, Consumer<SkcRelLabelEntity> selectiveCon, Consumer<SkcRelLabelEntityExample.Criteria> conditionCon, Consumer<List<SkcRelLabelEntity>> batchConsumer) {
        if (batchSize == 0) {
            return;
        }
        List<SkcRelLabelEntity> batchResult = new ArrayList<>();
        int protect = 0;
        int sizeTmp;
        AtomicLong cursor = new AtomicLong(0L);
        Consumer<SkcRelLabelEntity> selective = entity -> entity.id();
        if (selectiveCon != null) {
            selective = selective.andThen(selectiveCon);
        }
        do {
            List<SkcRelLabelEntity> toConsume = selectiveDb(
                Function.identity(),
                selective,
                example -> {
                    SkcRelLabelEntityExample.Criteria criteria = example.createCriteria()
                            .andIdGreaterThan(cursor.get());
                    example.setOrderByClause("id");
                    example.setLimit(batchSize);
                    conditionCon.accept(criteria);
            });
            sizeTmp = toConsume.size();
            if (sizeTmp == 0) {
                    return;
            }
            cursor.set(toConsume.stream().map(SkcRelLabelEntity::getId).max(Long::compareTo).orElse(0L));
            batchResult.clear();
            batchResult.addAll(new ArrayList<>(toConsume));
            batchConsumer.accept(batchResult);
            protect++;
            if (protect >= Short.MAX_VALUE) {
                throw new RuntimeException("循环次数超出最大值");
            }
        } while (sizeTmp == batchSize);
    }
}